package com.xxxy.component;

import com.xxxy.response.UserInfo;
import com.xxxy.redis.service.RedisService;
import lombok.extern.slf4j.Slf4j;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.*;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.springframework.beans.factory.annotation.Autowired;

import java.util.HashSet;
import java.util.Map;
import java.util.Set;

@Slf4j
public class UserRealm extends AuthorizingRealm {

    @Autowired
    private RedisService redisService;

    /**
     * 认证
     */
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
        log.info("------------用户角色认证-------------");
        UserToken token = (UserToken) authenticationToken;
        String id = token.getId();
        if(id != null){
            UserInfo userInfo = new UserInfo();
            Map<Object, Object> params = redisService.hGetAll(id);
            Set<String> roles = (Set<String>)params.get("roles");
            userInfo.setRoles(roles);
            setCredentialsMatcher(new MyHashedCredentialsMatcher());
            return new SimpleAuthenticationInfo(userInfo, "", getName());
        } else {
            throw  new UnknownAccountException();
        }
    }

    /**
     * 授权
     */
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
        log.info("------------用户角色权限授权-------------");
        UserInfo userInfo = (UserInfo)SecurityUtils.getSubject().getPrincipal();
        SimpleAuthorizationInfo authorizationInfo = new SimpleAuthorizationInfo();

        Set<String> permsSet = new HashSet<>();
        Set<String> rolesSet = userInfo.getRoles();
        for (String role : rolesSet) {
            Set<Object> sMember = redisService.sMembers(role);
            for (Object o : sMember) {
                for (Object o1 : (Set<Object>) o) {
                    permsSet.add((String) o1);
                }
            }
        }

        authorizationInfo.setStringPermissions(permsSet);
        authorizationInfo.setRoles(rolesSet);
        return authorizationInfo;
    }

}
